/*
获取程序命令行参数的宽字符串数组，并执分成单个的宽字符串，再依次转化为窄字节

CommandLineToArgvW、GetCommandLineW、LocalFree函数
wprintf函数
WideCharToMultiByte函数
HeapAlloc、HeapFree、GetProcessHeap、ZeroMemory函数

wprintf函数打印中文字符出错，先调用setlocale(LC_ALL, "chs");/_wsetlocale(LC_ALL, L"chs");设置语言环境
*/
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <locale.h>

void PrintArgvArray(LPWSTR * lpArgvArray, INT iNumArgs);
void WideToMul(WCHAR * wcArgv, INT cbMultiByte, LPVOID lpMem);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, INT iCmdShow)
{
    // 字符串数组，用以存储各个命令行参数
    LPWSTR * lpArgvArray;
    // 命令行参数计数
    INT iNumArgs;

    // _wsetlocale(LC_ALL, L"chs");
    setlocale(LC_ALL, "chs");

    // GetCommandLine函数获取的字符串包括程序名
    // szCmdLine参数不含程序名
    _tprintf(TEXT("szCmdLine：%s，GetCommandLine：%s。\n"), szCmdLine, GetCommandLine());

    // 获取命令行参数的字符串数组
    lpArgvArray = CommandLineToArgvW(GetCommandLineW(), &iNumArgs);

    if (lpArgvArray==NULL) {
        wprintf(L"error\n");
        return 1;
    }

    // 打印调用CommandLineToArgvW函数转换的命令行参数字符串数组
    PrintArgvArray(lpArgvArray, iNumArgs);
    
    // 释放分配给CommandLineToArgvW参数的内存
    LocalFree(lpArgvArray);

    return 0;
}

/* 打印调用CommandLineToArgvW函数转换的命令行参数字符串数组 */
void PrintArgvArray(LPWSTR * lpArgvArray, INT iNumArgs)
{
    INT iCnt=0;
    // 单个的命令行参数字符串
    WCHAR *wcArgv;
    LPVOID lpMem;

    for (;iCnt<iNumArgs;iCnt++) {
        // 单个的命令行参数字符串
        wcArgv = *(lpArgvArray+iCnt);
        // 打印单个的命令行参数字符串
        wprintf(L"第%d个参数，宽字符串：%s，长度：%lu。\t", iCnt, wcArgv, (wcslen(wcArgv)+1)*sizeof(WCHAR));

        // 宽字符串转窄字符串，获取转化后的窄字符串的长度
        INT cbMultiByte = WideCharToMultiByte(CP_ACP, 0, wcArgv, -1, NULL, 0, NULL, NULL);
        
        // 分配内存
        lpMem = HeapAlloc(GetProcessHeap(), 0, cbMultiByte);
        // 初始化为0
        ZeroMemory(lpMem, cbMultiByte);

        // 宽字符串转窄字符串
        WideToMul(wcArgv, cbMultiByte, lpMem);
        // 释放内存
        HeapFree(GetProcessHeap(), 0, lpMem);
    }
}


/* 宽字符串转窄字符串 */
void WideToMul(WCHAR * wcArgv, INT cbMultiByte, LPVOID lpMem)
{
    // 宽字符串转窄字符串的结果
    INT iWideToMulRes;
 
    // 宽字符串转化为窄字符串
    iWideToMulRes = WideCharToMultiByte(CP_ACP, 0, wcArgv, -1, lpMem, cbMultiByte, NULL, NULL);
    
    if (iWideToMulRes>0) {
        printf("窄字符串：%s，长度：%d。\n", (char *)lpMem, cbMultiByte);
    }
}